package com.bluezone.dec.common.exception;

import com.bluezone.dec.common.CodeEnum;
import com.bluezone.dec.common.JsonResult;
import com.google.common.base.Throwables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

//@ControllerAdvice("com.bluezone.dec.system.controller")
@Order(Ordered.HIGHEST_PRECEDENCE)
@RestControllerAdvice
@RestController
public class ExceptionController {

    private static final Logger log = LoggerFactory.getLogger(ExceptionController.class);

    /**
     * 用来接收前端校验的异常信息
     * 状态码使用200,使用ApiResult Code作为约束;
     *
     * @param e
     * @return
     */
    @ExceptionHandler({IllegalArgumentException.class, NullPointerException.class, IllegalStateException.class})
    public JsonResult frontVerify(Exception e) {
        log.warn("参数校验异常:", e);

        JsonResult result = new JsonResult().error();
        List<StackTraceElement> stackTraces = Throwables.lazyStackTrace(e);

        /**
         * 分析堆栈日志,如堆栈来源controller 则将msg返回给前端;
         *  捕获所有通过PreConditions.checkArgument抛出的异常
         * */
        for (StackTraceElement element : stackTraces) {
            if (element.getClassName().startsWith("com.google.common.base.Preconditions")) {
                result.setMsg(e.getMessage());
            }
        }
        result.setData(Throwables.getStackTraceAsString(e));

        return result;
    }

    /**
     * token无效异常
     */
    @ExceptionHandler(TokenInvalidException.class)
    public JsonResult tokenInvalidException(Exception e) {
        log.warn("token无效:", e);
        JsonResult result = new JsonResult();
        return result.sendCode(CodeEnum.TOKEN_INVALID);
    }

    /**
     * Exception大范围异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public JsonResult exceptionHandler(Exception e) {
        return wrapperException(e, new JsonResult().error(), "");
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public JsonResult exceptionHandler(HttpRequestMethodNotSupportedException e) {
        return wrapperException(e, new JsonResult().error(), "错误的请求(http method不匹配)");
    }

    private JsonResult wrapperException(Exception e, JsonResult state, String msg) {
        log.error("系统异常:", e);
        state.setMsg(msg);
        state.setData(Throwables.getStackTraceAsString(e));
        return state;
    }

}
